﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public abstract class OReportEffect
{
	public static OReportEffect Instance;

	public static GameObject forGameObject(int? gId) {
		if(gId == null) {
			return null;
		}
		
		return Instance.getGameObject((int)gId);
	}

	public static void playDetails (OReportDetail[] details, CallBack complete) {
		int detailsLength = details == null ? 0 : details.Length;
		if(detailsLength == 0) {
			AniBase.doComplete(complete);
			
		} else {
			int detailsIndex = 0;
			CallBack[] callBacks = new CallBack[1];
			CallBack effectComplete = ()=>{
				if(detailsIndex < detailsLength) {
					OReportDetail detail = details[detailsIndex];
					detailsIndex++;
					if(detail == null) {
						callBacks[0]();

					} else {
						Instance.playDetail(detail, callBacks[0]);
					}
					
				} else {
					AniBase.doComplete(complete);
				}
			};
			
			callBacks[0] = effectComplete;
			effectComplete();
		}
	}

	private bool inited;

	public readonly Dictionary<string, AniEffect> aniEffectDictionary = new Dictionary<string, AniEffect>();

	public readonly Dictionary<int?, Dictionary<int?, GameObject>> aniEffectBuffDic = new Dictionary<int?, Dictionary<int?, GameObject>>();
	
	public virtual void initEffects() {
		if(inited) {
			return;
		}

		inited = true;

		if(!aniEffectDictionary.ContainsKey("AB")) {
			aniEffectDictionary.Add("AB", new AniEffect_AB());
		}

		if(!aniEffectDictionary.ContainsKey("RB")) {
			aniEffectDictionary.Add("RB", new AniEffect_RB());
		}

		if(!aniEffectDictionary.ContainsKey("R")) {
			aniEffectDictionary.Add("R", new AniEffect_R());
		}
	}
	
	private void playDetail(OReportDetail detail, CallBack complete)
	{
		string effect = detail.effect;
		if(effect == null) {
			playDetailNull(detail, complete);
			
		} else {
			playEffectDetail(effect, detail, complete);
		}
	}
	
	protected virtual void playEffectDetail(string effect, OReportDetail detail, CallBack complete) {
		AniEffect aniEffect;
		aniEffectDictionary.TryGetValue(effect, out aniEffect);
		if(aniEffect == null) {
			try {
				GameObject effectObject = MonoBehaviour.Instantiate(Resources.Load("Effect_" + effect)) as GameObject;
				aniEffect = effectObject.GetComponent<AniEffectC>();
				if(aniEffect == null) {
					AniBase.doComplete(complete);
					MonoBehaviour.Destroy(effectObject);
					
				} else {
					aniEffect.play(detail, complete);
				}
				
			} catch(System.Exception e) {
				AniBase.doComplete(complete);
			}
			
		} else {
			aniEffect.play(detail, complete);
		}
	}
	
	protected virtual void playDetailNull(OReportDetail detail, CallBack complete) {
		AniBase.doComplete(complete);
	}

	public void clearAllBuff(int self) {
		Dictionary<int?, GameObject> buffDic = null;
		aniEffectBuffDic.TryGetValue(self, out buffDic);
		if(buffDic != null) {
			foreach(KeyValuePair<int?, GameObject> buffValue in buffDic) {
				MonoBehaviour.Destroy(buffValue.Value);
			}

			aniEffectBuffDic.Remove(self);
		}
	}

	public void clearAllBuffs() {
		foreach(KeyValuePair<int?, Dictionary<int?, GameObject>> aniEffectValue in aniEffectBuffDic) {
			foreach(KeyValuePair<int?, GameObject> buffValue in aniEffectValue.Value) {
				MonoBehaviour.Destroy(buffValue.Value);
			}
		}

		aniEffectBuffDic.Clear();
	}

	public abstract GameObject getGameObject(int gId);
}